JVM因OutOfMemoryError崩溃时,往往是内存泄漏导致的。在发布一款Java产品之前,通常应该对产品是否有内存泄漏问题进行测试。在标准的测试用例中,应该让应用程序持续运行一段时间,并检测堆中存货对象的数量来判断是否存在内存泄漏。良好测试程序应该会自动的、不断的对产品进行内存泄漏测试。
在开发JRockit Mission Control 4.0.0版本时,开发团队犯了过度自信的错误。正常情况下,在最终测试的时候,应该会使用 Memory Leak Detector工具来检查JRockit Mission Control中的编辑器是否被正常回收了。在那之前,这项测试都是由开发人员自己完成的,没有写入到测试规范中。结果就是,每次打开控制台或 Memleak编辑器时,都会使一个编辑器对象成为内存泄漏组成部分。当然,这个问题现在已经通过 Memory Leak Detector解决了。
Java中的内存泄漏问题可以通过 Management Console查看存活对象集属性来判断。但需要明确的是,短时间内,存活对象集的数量的不断上升并不意味着肯定是因为内存泄漏,而可能是因为Java应用程序的负载发生了变化,使应用程序消耗了更多内存,例如并发的用户数增加了。但如果存活对象集中对象的数量持续增加,则很有可能是好粗线内存泄漏了。
对堆中对象做详细分析主要有两种方式:
对于在线分析来说,内存趋势分析数据由垃圾回收器提供。由于垃圾回收器在垃圾回收的标记过程中就会遍历堆中所有的存货对象,因此,提供趋势分析数据并不会带来太大的性能损耗,而其生成的对象图谱则是分析内存分配趋势的重要数据。
JRockit使用的对转储格式是HPROF,与使用JVMTI(Java Virtual Machine Tool Interface)生成的堆转储格式相同。因此,由JRockit生成的堆转储可以使用任何支持HPROF格式的工具进行分析。更多有关HPROF格式的内容,请参见JRockit JDK的相关示例,具体位置在
JROCKIT_HOME/demo/jvmti/hprof/src/manual.html,有关JVMTI的内容,请参见JDK的相关文档。